import { HeaderSchema } from '../schema/schema';
import { ElementPropertyConfig } from '@farris/ide-property-panel';
import { HeaderProp } from '../property/property-config';
import { OperateUtils } from '../../../../utils/operate.utils';
import { BuilderHTMLElement, FarrisDesignBaseNestedComponent } from '@farris/designer-element';
import { FormPropertyChangeObject } from '../../../../entity/property-change-entity';
import { DomService, FormBindingType } from '@farris/designer-services';
import FdHeaderToolBarComponent from './fd-header-toolbar';
import { cloneDeep } from 'lodash-es';
import { DgControl } from '../../../../utils/dg-control';
import { HeaderDragDropManager } from '../drag-drop/dragAndDrapManager';

export default class FdHeaderComponent extends FarrisDesignBaseNestedComponent {

    /** 当前表单的展示模式，弹出类modal/独立页签类page/侧边滑出类slide 。
     * 优先取控件所属组件的展示类型，若没有配置，则取当前表单的展示类型
     */
    currentFormMode;

    // toolbar数据
    toolbarDatas;
    // 标识当前viewChangeKey
    get viewChangeKey(): string {
        return `viewChange-${this.key}`;
    }
    // 当前选中的项
    activeTypeItem;
    // 查找ref=form的项
    private formParent = undefined;
    private multiViewContainerEl = undefined;

    /** 主标题，因为主标题支持配置变量，为了页面不显示[object,object]，故将属性单独配置 */
    private mainTitle: string;

    headerToolBar: FdHeaderToolBarComponent;
    globalToolbar: any;

    /** 判断当前容器是否是固定的上下文的中间层级，这种容器不支持移动、不支持删除、并且隐藏间距 */
    private isInFixedContextRules = false;

    private dragManager: HeaderDragDropManager;

    constructor(component: any, options: any) {
        super(component, options);

        // 虽然类别为“容器”，但是实际没有子级节点
        this.category = 'container';

        this.dragManager = new HeaderDragDropManager(this);
        this.isInFixedContextRules = this.dragManager.checkIsInFixedContextRules();
    }


    getDefaultSchema(): any {

        return HeaderSchema;
    }

    /**
     * 为了适配按钮大小，增加ide-header-toolbar-XX 样式
     */
    getClassName(): string {
        let clsName = super.getClassName();
        if (this.component.toolbarBtnSize && this.component.toolbarBtnSize !== 'default') {
            clsName += ' ide-header-toolbar-' + this.component.toolbarBtnSize;
        }
        return clsName;
    }

    getTemplateName(): string {
        return 'Header';
    }
    hideNestedPaddingInDesginerView(): boolean {
        return true;
    }
    // 初始化
    init(): void {
        this.components = [];
        this.initToolbar();

        super.init();
    }

    private initToolbar() {
        // 当前showType
        const domService = this.options.designerHost.getService('DomService');
        this.currentFormMode = domService.module.showType || 'page';
        const comp = domService.getComponentByVMId(this.viewModelId);
        if (comp && comp.showType) {
            this.currentFormMode = comp.showType;
        }
        // viewChange赋值
        if (this.component.showViewChange && this.component.viewDatas) {
            // 初始化时，用结构上的或者默认的viewType
            this.activeTypeItem = OperateUtils.viewChangeInitActiveItem(this.component.currentTypeInDesignerView || this.component.viewDefaultType, this.activeTypeItem, this.component.viewDatas);
        }
        this.toolbarDatas = this.assembleHeaderToolbar();
        // 创建工具栏组件
        const toolBarComponent = this.getResponseToolbarStr();
        const options = Object.assign({}, this.options, { childComponents: [], parent: this, showType: this.currentFormMode });
        if (!this.headerToolBar) {
            this.headerToolBar = new FdHeaderToolBarComponent(toolBarComponent, options);
        } else {
            this.headerToolBar.reInit(toolBarComponent, this.currentFormMode);
        }
        this.headerToolBar.init();
        this.assembleMainTitle();

    }
    // 渲染模板
    render(children): any {
        this.initToolbar();

        return super.render(children || this.renderTemplate('Header', {
            toolbarDatas: this.toolbarDatas,
            currentFormMode: this.currentFormMode,
            viewChangeKey: this.viewChangeKey,
            getViewChangeStr: () => this.getViewChangeStr(),
            headerToolBar: this.headerToolBar,
            mainTitle: this.mainTitle
        }));
    }
    // 绑定事件
    attach(element: any): any {
        // key 如果有多个用 multi，单个用single
        this.loadRefs(element, {
            [this.viewChangeKey]: 'single'
        });
        // 必写
        const superAttach: any = super.attach(element);
        if (this.component.showViewChange && this.component.viewDatas) {
            // 绑定
            if (this.component.viewType === 'tile') {
                OperateUtils.bindTileEventForViewChange((obj, type, func) => { this.addEventListener(obj, type, func) }, this.component.viewDatas, this.activeTypeItem, this.refs[this.viewChangeKey], () => {
                    this.findMultiViewContainerEl();
                    return { multiViewContainerEl: this.multiViewContainerEl };
                }, (returnActiveItem) => {
                    this.activeTypeItem = returnActiveItem;
                    // 当前结构上保存
                    this.component.currentTypeInDesignerView = this.activeTypeItem['type'];
                    this.redraw();
                });

            } else if (this.component.viewType == 'dropdown') {
                OperateUtils.bindDropdownEventForViewChange((obj, type, func) => { this.addEventListener(obj, type, func) }, this.component.viewDatas, this.activeTypeItem, this.refs[this.viewChangeKey], () => {
                    this.findMultiViewContainerEl()
                    return { multiViewContainerEl: this.multiViewContainerEl };
                }, (returnActiveItem) => {
                    this.activeTypeItem = returnActiveItem;
                    // 当前结构上保存
                    this.component.currentTypeInDesignerView = this.activeTypeItem['type'];
                    this.redraw();
                });
            }
        }
        // 工具栏绑定事件
        const headerToolBarEle = element.querySelector('.farris-component-HeaderToolBar');
        if (headerToolBarEle) {
            this.headerToolBar.attach(headerToolBarEle);
        }

        // 将按钮的实例追加到header中，是为了从代码编辑器切换到可视化设计器时重新选中按钮
        if (this.headerToolBar) {
            const toolbarItemCmps = this.headerToolBar.components || [];
            this.components = this.components.concat(toolbarItemCmps);
        }

        this.setUnusedButtonsBasicInfoMap();

        // 必写
        return superAttach;
    }

    /**
     * 查找multiViewContainerEl
     */
    private findMultiViewContainerEl() {
        if (this.multiViewContainerEl) {
            return;
        }
        if (this.formParent === undefined) {
            this.formParent = OperateUtils.getFormParent(this.element);
        }
        if (this.formParent && this.multiViewContainerEl === undefined) {
            // 查找同组的元素
            this.multiViewContainerEl = this.formParent.querySelector('.farris-component-MultiViewContainer[viewchange=' + this.component.viewGroupIdentify + ']');
        }
    }
    // 构造Toolbar
    private assembleHeaderToolbar() {
        const toolbar = this.options.designerHost.getService('DomService').module.toolbar;
        // 获取全局按钮组
        this.globalToolbar = toolbar;
        if (!toolbar || !toolbar.items || !toolbar.items[this.viewModelId] ||
            !toolbar.configs || !toolbar.configs[this.currentFormMode] ||
            !toolbar.configs[this.currentFormMode][this.id]) {
            return [];
        }
        const buttonConfig = toolbar.configs[this.currentFormMode][this.id] as string[];
        if (!buttonConfig) {
            return [];
        }
        // 根据当前展示类型和当前控件id获取控件上所有的按钮配置
        const toolbarItems = [];
        buttonConfig.forEach(buttonId => {
            const buttonInfo = toolbar.items[this.viewModelId].find(item => buttonId === item.id);
            if (buttonInfo) {
                toolbarItems.push(buttonInfo);
            }
        });
        return this.assembleToolBarItem(toolbarItems);
    }
    // 构造ToolbarItem
    private assembleToolBarItem(items): any[] {
        if (!items || items.length === 0) {
            return [];
        }
        const data = [];
        items.forEach(item => {
            const dataItem = cloneDeep(item);
            dataItem.disabled = typeof (item.disable) === 'boolean' ? item.disable : false;


            if (item.items && item.items.length > 0) {
                dataItem.isDP = true;
                dataItem.items = this.assembleToolBarItem(item.items);
            }

            data.push(dataItem);
        });
        return data;
    }
    /**
     * 组装属性面板配置数据
     */
    getPropertyConfig(): ElementPropertyConfig[] {
        const serviceHost = this.options.designerHost;
        const prop: HeaderProp = new HeaderProp(serviceHost, this.viewModelId, this.componentId);
        const propertyConfig: ElementPropertyConfig[] = prop.getPropConfig(this.component);
        return propertyConfig;
    }
    /**
     * 获取view chagne的字符串
     */
    getViewChangeStr() {
        return OperateUtils.getViewChangeStr(this.component.viewDatas, this.component.viewType, this.activeTypeItem);
    }
    /**
     * 获取工具栏数据
     */
    getResponseToolbarStr() {

        const toolBar = {
            id: 'header-toolbar' + Math.random().toString(36).slice(2, 6),
            type: 'HeaderToolBar',
            appearance: {
                class: `f-toolbar ml-auto ${this.component.toolbarCls}`
            },
            title: '头部工具栏',
            items: this.toolbarDatas,
            toolbarCls: this.component.toolbarCls,
            toolbarBtnSize: this.component.toolbarBtnSize,
            toolbarPopDirection: this.component.toolbarPopDirection
        };
        return toolBar;
    }

    /**
     * 获取模板显示的主标题值。
     */
    private assembleMainTitle() {
        let mainTitle = this.component.mainTitle;
        // 适配主标题为变量的场景
        if (typeof (mainTitle) === 'object') {
            if (mainTitle.type === FormBindingType.Variable && mainTitle.path) {
                mainTitle = '变量：【' + mainTitle.path + '】';
            }
        }
        this.mainTitle = mainTitle;
    }
    /**
     * 属性变更后
     * @param changeObject 变更集
     */
    onPropertyChanged(changeObject: FormPropertyChangeObject): void {
        if (['visible', 'viewChangeType'].includes(changeObject.propertyID)) {
            return;
        }
        // 变更按钮个数，需要重新组装toolbarDatas数据
        if (changeObject.propertyID === 'toolbarDatas') {
            this.toolbarDatas = this.assembleHeaderToolbar();
        }
        if (changeObject.propertyID === 'mainTitle') {
            this.assembleMainTitle();
        }

        this.redraw();

    }

    checkCanDeleteComponent(): boolean {
        if (this.isInFixedContextRules) {
            return false;
        }
        return true;
    }
    checkCanMoveComponent(): boolean {
        if (this.isInFixedContextRules) {
            return false;
        }
        return true;
    }
    canAccepts(sourceElement: BuilderHTMLElement, targetElement?: BuilderHTMLElement): boolean {
        return false;
    }

    /**
     * 点击控件时计算控件工具栏位置
     */
    setPositionOfBtnGroup() {
        super.setPositionOfBtnGroup();

        //  header重绘后要重新计算内部工具栏的操作图标位置
        if (this.headerToolBar) {
            const toolbarEle = this.element.querySelector(`.dgComponentSelected[controltype='${DgControl.HeaderToolBar.type}']`);

            if (toolbarEle) {
                const toolbar = toolbarEle.querySelector('.component-btn-group') as HTMLElement;
                if (toolbar) {
                    toolbar.style.display = '';
                    const toolbarRect = toolbar.getBoundingClientRect();

                    const divPanel = toolbar.querySelector('div');
                    const divPanelRect = divPanel.getBoundingClientRect();

                    divPanel.style.top = toolbarRect.top + 'px';
                    divPanel.style.left = (toolbarRect.left - divPanelRect.width) + 'px';
                }
            }

        }
    }

    /**
     * 当前页面中未被使用的全局按钮，设置路径嘻嘻
     */
    private setUnusedButtonsBasicInfoMap() {
        const toolbar = this.options.designerHost.getService('DomService').module.toolbar;

        if (!toolbar || !toolbar.items || !toolbar.items[this.viewModelId] ||
            !toolbar.configs || !toolbar.configs[this.currentFormMode] ||
            !toolbar.configs[this.currentFormMode][this.id]) {
            return [];
        }
        const buttonConfig = toolbar.configs[this.currentFormMode][this.id] as string[];
        if (!buttonConfig) {
            return [];
        }

        const domService = this.options.designerHost.getService('DomService') as DomService;

        // 全局按钮若未被使用，仍需要设置路径信息，目的是为了方便交互面板显示
        let allUsedButtons = [];
        Object.keys(toolbar.configs[this.currentFormMode]).map(controlId => {
            allUsedButtons = allUsedButtons.concat(toolbar.configs[this.currentFormMode][controlId]);
        });


        toolbar.items[this.viewModelId].map(button => {
            if (!allUsedButtons.includes(button.id)) {
                domService.controlBasicInfoMap.set(button.id, {
                    showName: button.text,
                    parentPathName: button.text
                });
            }
        });
    }
}
